#!/usr/bin/env python

# Copyright (c) 2007 Mike Taylor
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#
# code layout/structure inspired by (well, ok... swiped from) pyTwerp
# http://code.google.com/p/pytwerp -- Mike Taylor and Decklin Foster
# 

"""
spinta.py - push Google Reader items to del.icio.us

That's all it does and it does that very simply :)

Usage:
    spinta

    default configuration file is ~/.spintarc

For the curious, spinta is Italian for push
(or at least that's what I hope it means!)

Requires:
    python 2.5+         http://python.org
    pydelicious         http://code.google.com/p/pydelicious
    feedparser          http://feedparser.org
"""

__version__    = '0.1'
__user_agent__ = 'Spinta/%s +http://code-bear.com/code/spinta/' % __version__

import os
import sys
import stat
import urllib
import urllib2
import cookielib
import ConfigParser


try:
    import pydelicious
except:
    print 'Unable to import pydelicious - the module can be found at http://code.google.com/p/pydelicious'
    sys.exit(1)

try:
    import feedparser
except:
    print 'Unable to import feedparser - the module can be found at http://feedparser.org'
    sys.exit(1)


def checkOptions():
    configfile = os.path.expanduser(os.path.join('~', '.spintarc'))

    if os.path.exists(configfile):
        cp = ConfigParser.RawConfigParser()

        cp.add_section('delicious')
        cp.add_section('google')

        cp.read([configfile])
    else:
        print >>sys.stderr, 'Configuration file ~/.spintarc not found'
        print >>sys.stderr, 'A sample has been created, please edit and re-run spinta'
        h = open(configfile, 'a')
        h.write('[delicious]\n')
        h.write('username=test\n')
        h.write('password=test\n')
        h.write('[google]\n')
        h.write('username=test@gmail.com\n')
        h.write('password=test\n')
        h.close()
        os.chmod(configfile, stat.S_IRUSR | stat.S_IWUSR)
        sys.exit(1)

    return cp

class GoogleReader():
    def __init__(self, username, password):
        self.header = { 'User-agent': __user_agent__ }
        self.data   = { 'service':  'reader',
                        'Email':    username,
                        'Passwd':   password,
                        'source':   __user_agent__,
                        'continue': 'http://www.google.com/',
                      }

        self.cookiejar = cookielib.LWPCookieJar()
        self.cookie    = urllib2.HTTPCookieProcessor(self.cookiejar)
        self.opener    = urllib2.build_opener([self.cookie])

        urllib2.install_opener(self.opener)

    def login(self):
        url     = 'https://www.google.com/accounts/ClientLogin'
        url     = url.encode('utf-8')
        post    = urllib.urlencode(self.data)
        request = urllib2.Request(url, post, self.header)

        self.cookiejar.add_cookie_header(request)

        response = urllib2.urlopen(request)
        sidinfo  = response.read()

        self.sid = None
        SID_ID   = 'SID='

        if SID_ID in sidinfo:
            p1       = sidinfo.find(SID_ID)
            p2       = sidinfo.find('\n', p1)
            self.sid = sidinfo[p1 + len(SID_ID):p2]

        if self.sid is not None:
            self.SIDcookie = cookielib.Cookie(version=0, name='SID', value=self.sid, port=None, port_specified=False, domain='.google.com', domain_specified=True, domain_initial_dot=True, path='/', path_specified=True, secure=False, expires='1600000000', discard=False, comment=None, comment_url=None, rest={})
            self.cookiejar.set_cookie(self.SIDcookie)

    def feed(self, name='broadcast'):
        request = urllib2.Request('http://www.google.com/reader/atom/user/-/state/com.google/%s' % name, None, self.header)

        self.cookiejar.add_cookie_header(request)

        response = urllib2.urlopen(request)

        return response.read()


def main():
    try:
        cp = checkOptions()
        gr = GoogleReader(cp.get('google', 'username'), cp.get('google', 'password'))

        print 'Logging into Google Reader'

        gr.login()

        print 'Pulling feed'

        data = gr.feed('broadcast')
        feed = feedparser.parse(data)

        if feed['bozo']:
            print 'bozo flag returned'

        nCount  = len(feed['entries'])
        nPosted = 0

        if nCount > 0:
            items = feed['entries']
            d     = pydelicious.DeliciousAPI(cp.get('delicious', 'username'), cp.get('delicious', 'password'))

            print 'processing %d items' % len(items)

            # available attributes for each item
            # author, link, published, source, summary, tags, title, updated
            # published and updated are strings
            # tags is a list of dictionaries with keys: label, scheme and term

            for item in items:
                if 'published' in item:
                    published = item.published
                else:
                    published = item.updated

                tags = ''
                for tag_dict in item.tags:
                    tags += '%s ' % tag_dict['label']

                result      = d.posts_add(item.link, item.title, item.description, tags=tags, dt=published)
                result, msg = result['result']

                print '%s: %s' % (item.link, msg)

                if result:
                    nPosted += 1

            print '%d of %d items posted' % (nPosted, nCount)

    except KeyboardInterrupt:
        sys.exit(0)

if __name__ == "__main__":
    main()
